# from @鹤翔万里

from manimlib import *


class ColorText(Text):
    CONFIG = {
        "size": 0.8,
        "font": "Consolas",
        "t2c": {
            '"': YELLOW_E,
            'np': BLACK,
            'array': BLUE_D,
            '~': WHITE
        },
        "color": GREY_D,
    }

    def __init__(self, color, name=None, background_color=WHITE, **kwargs):
        if name:
            Text.__init__(self, name, color=color, **kwargs)
        else:
            if isinstance(color, str):
                Text.__init__(self, '"' + color + '"', color=color, **kwargs)
            elif color[0] > 1 or color[1] > 1 or color[2] > 1:
                name = 'np.array([{},~{},~{}])'.format(
                    str(int(color[0])).rjust(3, "~"),
                    str(int(color[1])).rjust(3, "~"),
                    str(int(color[2])).rjust(3, "~")
                )
                Text.__init__(self, name, color=rgb_to_color(color / 255), **kwargs)
                self[10:name.index(",")].set_color(RED)
                self[name.index(",") + 2:name.index(",", name.index(",") + 1)].set_color(GREEN)
                self[name.index(",", name.index(",") + 1) + 2:-2].set_color(BLUE)
                self.set_color_by_t2c({"~": background_color})
            else:
                name = 'np.array([{:.1f},~{:.1f},~{:.1f}])'.format(color[0], color[1], color[2])
                Text.__init__(self, name, **kwargs)
                self[10:name.index(",")].set_color(RED)
                self[name.index(",") + 2:name.index(",", name.index(",") + 1)].set_color(GREEN)
                self[name.index(",", name.index(",") + 1) + 2:-2].set_color(BLUE)
                self.set_color_by_t2c({"~": background_color})


class CodeLine(Text):
    CONFIG = {
        't2c': {
            '0': "#FAb763",
            '1': "#FAb763",
            '2': "#FAb763",
            '3': "#FAb763",
            '4': "#FAb763",
            '5': "#FAb763",
            '6': "#FAb763",
            '7': "#FAb763",
            '8': "#FAb763",
            '9': "#FAb763",
            "'": '#A3CE9E',
            '"': '#A3CE9E',
            'return': "#C594C5",
            'def': "#C594C5",
            'interpolate': "#60B4B4",
            'start': "#FAB763",
            'end': "#FAB763",
            'alpha': "#FAB763",
            ":": "#FA9044",
            "+": "#FA9044",
            "*": "#FA9044",
            "/": "#FA9044",
            "-": "#FA9044",
            ">": "#FA9044",
            "<": "#FA9044",
            "%": "#FA9044",
            "&": "#FA9044",
            "=": "#FA9044",
            "!": "#FA9044",
            "|": "#FA9044",
            "^": "#FA9044",
            ",": GREY,
            "class": "#C594C5",
            ".": GREY,
            "self": "#D86066",
            "play": "#569CD6",
            "add_updater": "#569CD6",
            "functions": "#569CD6",
            "UP": "#FAB763",
            "(": GREY_B,
            ")": GREY_B,
            '\\': GREY,
            "generate_target": "#569CD6",
            'lambda': '#C594C5',
            '~': '#1f252a',
        },
        't2s': {
            'lambda': 'ITALIC',
            'self': 'ITALIC',
            'def': 'ITALIC',
            'class': 'ITALIC',
        },
        'font': 'Monaco_fix',
        'size': 24,
        'color': "#e0e0e0",
    }

    def __init__(self, text, **kwargs):
        Text.__init__(self, text, **kwargs)


class CodeLines(VGroup):
    CONFIG = {
        'scale_factor': 0.65,
        'line_buff': 0.15
    }

    def __init__(self, *codes, **kwargs):
        digest_config(self, kwargs)
        super().__init__(*[CodeLine(code, **kwargs).scale(self.scale_factor) for code in codes])
        if len(codes) > 1:
            self.arrange(DOWN, aligned_edge=LEFT, buff=self.line_buff)
